home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / glibc108.gz / glibc108 / glibc-1.08.1 / mach / __msg_dest.c next >
C/C++ Source or Header  |  1993-08-03  |  4KB  |  153 lines

  1. /* 
  2.  * Mach Operating System
  3.  * Copyright (c) 1991,1990 Carnegie Mellon University
  4.  * All Rights Reserved.
  5.  * 
  6.  * Permission to use, copy, modify and distribute this software and its
  7.  * documentation is hereby granted, provided that both the copyright
  8.  * notice and this permission notice appear in all copies of the
  9.  * software, derivative works or modified versions, and any portions
  10.  * thereof, and that both notices appear in supporting documentation.
  11.  * 
  12.  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  13.  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14.  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15.  * 
  16.  * Carnegie Mellon requests users of this software to return to
  17.  * 
  18.  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
  19.  *  School of Computer Science
  20.  *  Carnegie Mellon University
  21.  *  Pittsburgh PA 15213-3890
  22.  * 
  23.  * any improvements or extensions that they make and grant Carnegie Mellon
  24.  * the rights to redistribute these changes.
  25.  */
  26. /*
  27.  * HISTORY
  28.  * $Log:    mach_msg_destroy.c,v $
  29.  * Revision 2.4  91/05/14  17:53:15  mrt
  30.  *     Correcting copyright
  31.  * 
  32.  * Revision 2.3  91/02/14  14:17:43  mrt
  33.  *     Added new Mach copyright
  34.  *     [91/02/13  12:44:15  mrt]
  35.  * 
  36.  * Revision 2.2  90/08/06  17:24:22  rpd
  37.  *     Created.
  38.  * 
  39.  */
  40.  
  41. #if 1
  42. #include <mach.h>
  43. #else
  44. /* This is what CMU did, but that fails to declare some used functions.  */
  45. #include <mach/port.h>
  46. #include <mach/message.h>
  47. #include <mach_init.h>
  48. #endif
  49.  
  50. static void mach_msg_destroy_port();
  51. static void mach_msg_destroy_memory();
  52.  
  53. /*
  54.  *    Routine:    mach_msg_destroy
  55.  *    Purpose:
  56.  *        Deallocates all port rights and out-of-line memory
  57.  *        found in a received message.
  58.  */
  59.  
  60. void
  61. __mach_msg_destroy(msg)
  62.     mach_msg_header_t *msg;
  63. {
  64.     mach_msg_bits_t mbits = msg->msgh_bits;
  65.  
  66.     /*
  67.      *    The msgh_local_port field doesn't hold a port right.
  68.      *    The receive operation consumes the destination port right.
  69.      */
  70.  
  71.     mach_msg_destroy_port(msg->msgh_remote_port, MACH_MSGH_BITS_REMOTE(mbits));
  72.  
  73.     if (mbits & MACH_MSGH_BITS_COMPLEX) {
  74.     vm_offset_t saddr;
  75.     vm_offset_t eaddr;
  76.  
  77.     saddr = (vm_offset_t) (msg + 1);
  78.     eaddr = (vm_offset_t) msg + msg->msgh_size;
  79.  
  80.     while (saddr < eaddr) {
  81.         mach_msg_type_long_t *type;
  82.         mach_msg_type_name_t name;
  83.         mach_msg_type_size_t size;
  84.         mach_msg_type_number_t number;
  85.         boolean_t is_inline;
  86.         vm_size_t length;
  87.         vm_offset_t addr;
  88.  
  89.         type = (mach_msg_type_long_t *) saddr;
  90.         is_inline = type->msgtl_header.msgt_inline;
  91.         if (type->msgtl_header.msgt_longform) {
  92.             name = type->msgtl_name;
  93.             size = type->msgtl_size;
  94.             number = type->msgtl_number;
  95.             saddr += sizeof(mach_msg_type_long_t);
  96.         } else {
  97.             name = type->msgtl_header.msgt_name;
  98.             size = type->msgtl_header.msgt_size;
  99.             number = type->msgtl_header.msgt_number;
  100.             saddr += sizeof(mach_msg_type_t);
  101.         }
  102.  
  103.         /* calculate length of data in bytes, rounding up */
  104.         length = ((((number * size) + 7) >> 3) + 3) &~ 3;
  105.  
  106.         addr = is_inline ? saddr : * (vm_offset_t *) saddr;
  107.  
  108.         if (MACH_MSG_TYPE_PORT_ANY(name)) {
  109.         mach_port_t *ports = (mach_port_t *) addr;
  110.         mach_msg_type_number_t i;
  111.  
  112.         for (i = 0; i < number; i++)
  113.             mach_msg_destroy_port(*ports++, name);
  114.         }
  115.  
  116.         if (is_inline) {
  117.         /* inline data sizes round up to int boundaries */
  118.         saddr += length;
  119.         } else {
  120.         mach_msg_destroy_memory(addr, length);
  121.         saddr += sizeof(vm_offset_t);
  122.         }
  123.     }
  124.     }
  125. }
  126.  
  127. static void
  128. mach_msg_destroy_port(port, type)
  129.     mach_port_t port;
  130.     mach_msg_type_name_t type;
  131. {
  132.     if (MACH_PORT_VALID(port)) switch (type) {
  133.       case MACH_MSG_TYPE_PORT_SEND:
  134.       case MACH_MSG_TYPE_PORT_SEND_ONCE:
  135.     (void) __mach_port_deallocate(__mach_task_self(), port);
  136.     break;
  137.  
  138.       case MACH_MSG_TYPE_PORT_RECEIVE:
  139.     (void) __mach_port_mod_refs(__mach_task_self(), port,
  140.                     MACH_PORT_RIGHT_RECEIVE, -1);
  141.     break;
  142.     }
  143. }
  144.  
  145. static void
  146. mach_msg_destroy_memory(addr, size)
  147.     vm_offset_t addr;
  148.     vm_size_t size;
  149. {
  150.     if (size > 0)
  151.     (void) __vm_deallocate(__mach_task_self(), addr, size);
  152. }
  153.